﻿/*!
 *MediaPlayerBySHF v1.1.2
 *Author:盛浩峰
 *Date:2014-05-12
 *http://www.cnblogs.com/iamshf
 *http://wonder-world.appspot.com
 *增加为播放器添加canplaythrough事件
*/
;
function onSilverlightError(sender, args) {
    var appSource = "";
    if (sender != null && sender != 0) {
        appSource = sender.getHost().Source;
    }

    var errorType = args.ErrorType;
    var iErrorCode = args.ErrorCode;

    if (errorType == "ImageError" || errorType == "MediaError") {
        return;
    }

    var errMsg = "Silverlight 应用程序中未处理的错误 " + appSource + "\n";

    errMsg += "代码: " + iErrorCode + "    \n";
    errMsg += "类别: " + errorType + "       \n";
    errMsg += "消息: " + args.ErrorMessage + "     \n";

    if (errorType == "ParserError") {
        errMsg += "文件: " + args.xamlFile + "     \n";
        errMsg += "行: " + args.lineNumber + "     \n";
        errMsg += "位置: " + args.charPosition + "     \n";
    }
    else if (errorType == "RuntimeError") {
        if (args.lineNumber != 0) {
            errMsg += "行: " + args.lineNumber + "     \n";
            errMsg += "位置: " + args.charPosition + "     \n";
        }
        errMsg += "方法名称: " + args.methodName + "     \n";
    }

    throw new Error(errMsg);
}
(function ($) {
    //#region 公共变量
    var isDraging=true;
    //#endregion

    //#region 播放器公共方法
    function CreateMedia(objOptions){
        var htmlMedia = "<div class=\"MediaBySHFContainer\" id=\"MediaBySHFContainer"+objOptions.strMediaID+"\">";
        //<!--播放器组件(Silverlight Or Html5(audio,video))容器-->
        htmlMedia+="<div class=\"MediaPlayerContainer\" id=\"MediaPlayerContainer"+objOptions.strMediaID+"\"></div>";
        //<!--播放器控制部分-->
        htmlMedia+="<div class=\"MediaControllerContainer\" id=\"MediaControllerContainer"+objOptions.strMediaID+"\">";
        htmlMedia+="<input type=\"button\" class=\"btnControl btnControlPlay\" id=\"btnControlPlay"+objOptions.strMediaID+"\" />";
        htmlMedia+="<input type=\"button\" class=\"btnControl btnControlStop\" id=\"btnControlStop"+objOptions.strMediaID+"\" />";
        //<!--进度条部分-->
        htmlMedia+="<div class=\"ProcessBarContainer\" id=\"ProcessBarContainer"+objOptions.strMediaID+"\">";
        htmlMedia+="<div class=\"ProcessBarCommon ProcessBarLeft\" id=\"ProcessBarLeft"+objOptions.strMediaID+"\"></div>";
        htmlMedia+="<div class=\"ProcessBar\" id=\"ProcessBar"+objOptions.strMediaID+"\">";
        htmlMedia+="<div class=\"ProcessSlider\" id=\"ProcessSlider"+objOptions.strMediaID+"\"></div>";
        htmlMedia+="</div>";
        htmlMedia+="<div class=\"ProcessBarCommon ProcessBarRight\" id=\"ProcessBarRight"+objOptions.strMediaID+"\"></div>";
        htmlMedia+="</div>";
        //<!--音量控制部分-->
        htmlMedia+="<div class=\"VolumeControlContainer\" id=\"VolumeControlContainer"+objOptions.strMediaID+"\">";
        htmlMedia+="<input type=\"button\" class=\"btnControl btnControlVolume\" id=\"btnControlVolume"+objOptions.strMediaID+"\" />";
        htmlMedia+="<div class=\"VolumeBar\" id=\"VolumeBar"+objOptions.strMediaID+"\"><div class=\"VolumeSlider\" id=\"VolumeSlider"+objOptions.strMediaID+"\"></div></div>";
        htmlMedia+="</div>";
        //<!--状态栏-->
        htmlMedia+="<span class=\"MediaStatus\" id=\"MediaStatus"+objOptions.strMediaID+"\"></span>";
        htmlMedia+="</div>";
        //<!--播放器控制部分-->
        htmlMedia+="</div>";
        objOptions.objParentElement.innerHTML+=htmlMedia;
    }
    function ConfigMediaPlayer(objMedia){
        ///<summary>
        ///配置播放器
        ///</summary>
        ///<param name="objMedia" type="Object">播放器对象</param>
        var objElementProcess = $("#ProcessSlider"+objMedia.Options.strMediaID);
        var iObjElementProcessInitPosi = parseInt(objElementProcess.css("left"),10)
        objElementProcess.DragBySHF({
            isLockY: true,
            isLimit: true,
            minLeft: 0,
            maxLeft: 150,
            funStart:function(){isDraging=false;},
            funStop:function(objOptions){
                //注：位置计算方法
                //当前位置-偏移量/总长度*总时长
                //偏移量=初始位置+最小偏移量
                objMedia.SetMediaPosition(objMedia.GetTotalDuration()*(parseFloat(objElementProcess.css("left"))-(iObjElementProcessInitPosi+objOptions.minLeft))/(objOptions.maxLeft-objOptions.minLeft));
                isDraging=true;
            }
        });
        $("#VolumeSlider"+objMedia.Options.strMediaID).DragBySHF({
            isLockY: true,
            isLimit: true,
            minLeft: -52,
            maxLeft: 48,
            funDraging: function(iPosiX, iPosiY, objOptions){objMedia.SetVolume(iPosiX+2);}
        });
        if(objMedia.Options.isShowControls){
            ShowControl(objMedia);
        }
        objMedia.SetVolume(50);
    }
    function ShowControl(objMedia){
        $("#MediaControllerContainer"+objMedia.Options.strMediaID).show();
        AddControlEvent(objMedia);
        objMedia.Options.isShowControls=true;
    }
    function HideControl(objMedia){
        $("#MediaControllerContainer"+objMedia.Options.strMediaID).hide();
        RemoveControlEvent(objMedia);
        objMedia.Options.isShowControls=false;
    }
    function AddControlEvent(objMedia){
        $("#btnControlPlay"+objMedia.Options.strMediaID).click(function(){
            if($(this).hasClass("btnControlPlay")){
                objMedia.Play();
            }
            else if($(this).hasClass("btnControlPause")){
                objMedia.Pause();
            }
        });
        $("#btnControlStop"+objMedia.Options.strMediaID).click(function(){
            objMedia.Stop();
        });
        objMedia.AddEvent(objMedia.EventHandler.Ended,"MediaEnded"+objMedia.Options.strMediaID,"");
        objMedia.AddEvent(objMedia.EventHandler.TimeUpdate,"MediaTimeUpdate"+objMedia.Options.strMediaID,"");
        if(!objMedia.EventHandler.CurrentStateChanged){
            objMedia.AddEvent(objMedia.EventHandler.CurrentStateChanged,"MediaCurrentStateChanged"+objMedia.Options.strMediaID,"");
        }
    }
    function RemoveControlEvent(objMedia){
        $("#btnControlPlay"+objMedia.Options.strMediaID).unbind("click");
        $("#btnControlStop"+objMedia.Options.strMediaID).unbind("click");
        objMedia.RemoveEvent(objMedia.EventHandler.Ended,"MediaEnded"+objMedia.Options.strMediaID);
        objMedia.RemoveEvent(objMedia.EventHandler.TimeUpdate,"MediaTimeUpdate"+objMedia.Options.strMediaID);
        objMedia.AddEvent(objMedia.EventHandler.CurrentStateChanged,"MediaCurrentStateChanged"+objMedia.Options.strMediaID);
    }
    function CreateMediaEvent(objMedia){
        if(!window["MediaTimeUpdate"+objMedia.Options.strMediaID])
        {
            window["MediaTimeUpdate"+objMedia.Options.strMediaID]=function(){
                isDraging&&$("#ProcessSlider"+objMedia.Options.strMediaID).css("left", (objMedia.GetCurrentPosition()/objMedia.GetTotalDuration()*150+0-7)+"px");
            }
        }
        if(!window["MediaEnded"+objMedia.Options.strMediaID])
        {
            window["MediaEnded"+objMedia.Options.strMediaID]=function(){
                objMedia.Stop();
            }
        }
        if(!window["MediaCurrentStateChanged"+objMedia.Options.strMediaID]){
            window["MediaCurrentStateChanged"+objMedia.Options.strMediaID]=function(strCurrentState){
                $("#MediaStatus"+objMedia.Options.strMediaID).text(strCurrentState);
            }
        }
    }
    //#endregion 播放器公共方法

    //#region HTML5播放器
    function SoundHtml5(objOptions) {
        var _this = this;
        var objSound = document.createElement("audio");
        CreateMedia(objOptions);
        this.MediaElementGet=function(){
            ///<summary>
            ///获取多媒体对象
            ///<summary>
            return objSound;
        }
        this.Ready=function(funReady){
            document.getElementById("MediaPlayerContainer"+objOptions.strMediaID).appendChild(objSound);
            ConfigMediaPlayer(_this)
            if ($.isFunction(funReady)) {
                funReady();
            }
        }
    }
    SoundHtml5.prototype={
        Options:{},
        EventHandler:{"Ended":"ended","TimeUpdate":"timeupdate","Canplaythrough":"canplaythrough"},
        EventList:{},
        Play:function(){
            $("#btnControlPlay"+this.Options.strMediaID).removeClass("btnControlPlay").addClass("btnControlPause");
            this.MediaElementGet().play();
        },
        Pause:function(){
            $("#btnControlPlay"+this.Options.strMediaID).removeClass("btnControlPause").addClass("btnControlPlay");
            this.MediaElementGet().pause();
        },
        Stop:function(){
            $("#btnControlPlay"+this.Options.strMediaID).removeClass("btnControlPause").addClass("btnControlPlay");
            this.Pause();
            this.SetMediaPosition(0);
        },
        SetMedia:function(strUrl){
            this.MediaElementGet().src = strUrl;
            this.MediaElementGet().load();
        },
        SetAutoPlay:function(isAutoPlay){
            this.MediaElementGet().autoplay = isAutoPlay;
        },
        SetVolume:function(iVolume){
            iVolume=(iVolume/100).toFixed(1);
            this.MediaElementGet().volume = iVolume;
        },
        AddEvent:function(strEventType, strFunName, strParams){
            if(!this.EventList[strFunName]){
                this.EventList[strFunName]=function(){window[strFunName](strParams);}
                this.MediaElementGet().addEventListener(strEventType, this.EventList[strFunName]);
            }
        },
        RemoveEvent:function(strEventType, strFunName){
            if(this.EventList[strFunName]){
                this.MediaElementGet().removeEventListener(strEventType, this.EventList[strFunName]);
                delete this.EventList[strFunName];
            }
        },
        GetCurrentPosition:function(){
            return this.MediaElementGet().currentTime;
        },
        GetTotalDuration:function(){
            return this.MediaElementGet().duration;
        },
        SetMediaPosition:function(dSeconds){
            if(this.MediaElementGet().readyState>0){
                this.MediaElementGet().currentTime=dSeconds;
            }
        },
        ShowMediaControl:function(){
            ShowControl(this);
        },
        HideMediaControl:function(){
            HideControl(this);
        }
    };
    //#endregion HTML5播放器

    //#region Silverlight播放器
    function MediaSilverlight(objOptions){
        var _this=this;
        var objMediaElement;//多媒体对象（Audio、Video、Silverlight对象）
        CreateMedia(objOptions);
        this.MediaElementGet=function(){
            ///<summary>
            ///获取多媒体对象
            ///<summary>
            return objMediaElement;
        }
        this.Ready=function(funReady){
            ///<summary>
            ///多媒体对象创建成功之后执行的方法
            ///<summary>
            ///<param name="funReady" type="Function">方法对象</param>
            document.getElementById("MediaPlayerContainer"+objOptions.strMediaID).innerHTML += Silverlight.createObjectEx({
                source: "http://192.168.1.66/MediaBySHF/Web/ClientBin/MediaPlayerBySHF.xap",
                id: "slMedia"+objOptions.strMediaID,
                properties: {
                    width: "100%",
                    height: "100%",
                    version: "5.0.61118.0",
                    background:"transparent",
                    autoUpgrade:"true",
                    windowless:"true",
                    enableHtmlAccess:"true",
                    //allowHtmlPopupWindow:"true",
                    alert: "您的电脑未安装Silverlight或者版本过低，请安装最新版本！"
                },
                events: {
                    onError: onSilverlightError,
                    onLoad: function (plugIn, userContext, sender) {
                        //注1：使用Microsoft Ajax Minifier生成min文件时会忽略后两个参数，需手动添加
                        //注2：跨域引用时无法访问到sender
                        //objMediaElement = sender.getHost().Content.HtmlPage;
                        
                        objMediaElement=document.getElementById(plugIn.id).Content.HtmlPage;
                        ConfigMediaPlayer(_this);
                        if ($.isFunction(funReady)) {
                            funReady();
                        }
                    }
                },
                context: ""
            });
        }
    }
    MediaSilverlight.prototype={
        Options:{},
        EventHandler:{"Ended":"MediaEnded","TimeUpdate":"MediaTimeUpdate","CurrentStateChanged":"MediaCurrentStateChanged","Canplaythrough":"MediaOpened"},
        Play:function(){
            $("#btnControlPlay"+this.Options.strMediaID).removeClass("btnControlPlay").addClass("btnControlPause");
            this.MediaElementGet().Play();
        },
        Pause:function(){
            $("#btnControlPlay"+this.Options.strMediaID).removeClass("btnControlPause").addClass("btnControlPlay");
            this.MediaElementGet().Pause();
        },
        Stop:function(){
            $("#btnControlPlay"+this.Options.strMediaID).removeClass("btnControlPause").addClass("btnControlPlay");
            this.MediaElementGet().Stop();
        },
        SetMedia:function(strUrl){
            this.MediaElementGet().SetMedia(strUrl);
        },
        SetAutoPlay:function(isAutoPlay){
            this.MediaElementGet().SetAutoPlay(isAutoPlay);
        },
        SetVolume:function(iVolume){
            iVolume=(iVolume/100).toFixed(1);
            this.MediaElementGet().SetVolume(iVolume);
        },
        AddEvent:function(strEventType, strFunName, strParams){
            this.MediaElementGet().AddMediaEvent(strEventType, strFunName, strParams);
        },
        RemoveEvent:function(strEventType, strFunName){
            this.MediaElementGet().RemoveMediaEvent(strEventType, strFunName);
        },
        GetCurrentPosition:function(){
            return this.MediaElementGet().GetCurrentPosition();
        },
        GetTotalDuration:function(){
            return this.MediaElementGet().GetTotalDuration();
        },
        SetMediaPosition:function(dSeconds){
            this.MediaElementGet().SetMediaPosition(dSeconds);
        },
        ShowMediaControl:function(){
            ShowControl(this);
        },
        HideMediaControl:function(){
            HideControl(this);
        }
    };
    //#endregion Silverlight播放器

    //#region 扩展插件
    $.extend({
        MediaBySHF: {
            Create: function (objParams) {
                ///<summary>
                ///创建多媒体对象
                ///</summary>
                ///<return>多媒体对象</return>
                var isHtml5Support=false;
                var objMedia;
                var objDefaultSettings = {
                    objParentElement: document.body, //包含多媒体的父级对象
                    strMediaID: new Date().getTime(),
                    strMediaType:"audio",//媒体类型(video|audio)
                    strMediaCodeType:"audio/mpeg",
                    isShowControls:true//是否显示播放器控制按钮
                };
                if($("#MediaBySHFContainer"+objDefaultSettings.strMediaID)){
                    objDefaultSettings.strMediaID=new Date().getTime();
                }
                var objOptions = $.extend({},objDefaultSettings, objParams);

                var objMediaElement = document.createElement(objOptions.strMediaType);
                if((objMediaElement != null) && (objMediaElement.canPlayType) && (objMediaElement.canPlayType(objOptions.strMediaCodeType))){
                    if(objOptions.strMediaType=="audio"){
                        objMedia=new SoundHtml5(objOptions);
                    }
                    if(objOptions.strMediaType=="video"){
                    }
                }
                else{
                    objMedia=new MediaSilverlight(objOptions);
                }
                objMedia.Options=objOptions;
                CreateMediaEvent(objMedia);
                return objMedia;
            }
        }
    })
    //#endregion 扩展插件
})(jQuery);